package pay

import (
	"context"
	"encoding/json"
	"git.900sui.cn/kc/base/common/functions"
	"git.900sui.cn/kc/base/common/toolLib"
	"git.900sui.cn/kc/rpcPay/common/lib"
	"git.900sui.cn/kc/rpcPay/common/models"
	"git.900sui.cn/kc/rpcPay/constkey"
	_const "git.900sui.cn/kc/rpcPay/lang/const"
	"git.900sui.cn/kc/rpcinterface/interface/bus"
	"git.900sui.cn/kc/rpcinterface/interface/order"
	pay2 "git.900sui.cn/kc/rpcinterface/interface/pay"
	"github.com/shopspring/decimal"
	"github.com/tidwall/gjson"
)

type icbc struct {
}

//生成二维码
func (i *icbc) PayQr(payInfo *pay2.PayInfo) (string, error) {
	return lib.IcbcPay.QrCode(payInfo)
}

func (i *icbc) PayH5(payInfo *pay2.PayInfo) (string, error) {

	return lib.IcbcPay.H5AliPay(payInfo)
}

func (i *icbc) PayH5New(payInfo *pay2.PayInfo, p *pay2.PayH5) (err error) {
	return nil
}

//微信小程序付款
func (i *icbc) PayWxApp(payInfo *pay2.PayInfo) (*gjson.Result, error) {
	return lib.IcbcPay.WxappPay(payInfo)
}

// 微信公众号支付
func (i *icbc) PayWxOfficial(payInfo *pay2.PayInfo) (*gjson.Result, error) {
	return lib.IcbcPay.PayWxOfficial(payInfo)
}

//获取App支付信息
func (i *icbc) PayApp(payInfo *pay2.PayInfo) (*gjson.Result, error) {
	return lib.IcbcPay.PayApp(payInfo)
}

//获取支付签名字符串
func (i *icbc) PayAppSign(payInfo *pay2.PayInfo) (string, error) {
	return "", nil
}

//异步回调通知
func (i *icbc) Notify(data string) (*pay2.PayNotify, error) {

	body, err := lib.IcbcPay.DisposeNotifyData(data)
	if err != nil {
		return nil, err
	}
	if body.Get(constkey.RETURN_CODE).Int() != 0 {
		return nil, toolLib.CreateKcErr(_const.PAY_ERROR)
	}
	//手续费，通知结果中没有手续费字段，如何处理？？
	fen := decimal.NewFromInt(100)
	fee := decimal.NewFromInt(0)
	//body.ForEach(func(key, value gjson.Result) bool {
	//	if strings.HasSuffix(key.String(), "Fee") {
	//		fee = fee.Add(decimal.NewFromInt(value.Int()))
	//	}
	//	return true
	//})

	payTime := functions.StrtoTime(body.Get("pay_time").String(), "20060102150405")
	return &pay2.PayNotify{
		OrderSn:    body.Get("out_trade_no").String(),
		PayTime:    payTime,
		PayAmount:  decimal.NewFromInt(body.Get("payment_amt").Int()).Div(fen).String(),
		PayFee:     fee.Div(fen).String(),
		PaySn:      body.Get("order_id").String(),
		PayStatus:  pay2.PAY_Suc,
		PayChannel: order.PAY_CHANNEL_icbc,
		PayType:    int(body.Get("pay_type").Int()),
	}, nil
}

//异步回调响应
func (i *icbc) NotifyResponse(ctx context.Context, args *pay2.ArgsNotify) (*pay2.ReplyNotifyResponse, error) {
	reqBody, err := lib.IcbcPay.DisposeNotifyData(args.Data)
	var (
		returnCode int64
		returnMsg  string
		reply      pay2.ReplyNotifyResponse
	)
	if err != nil {
		if err.Error() == "crypto/rsa: verification error" {
			returnCode, returnMsg = 400017, "签名验证失败"
		} else {
			returnCode, returnMsg = 100000, "未知错误"
		}
	}else{
		returnCode = reqBody.Get(constkey.RETURN_CODE).Int()
		returnMsg = reqBody.Get(constkey.RETURN_MSG).String()
	}
	reply.ResponseJsonStr = notifyResponseMsg(returnCode, returnMsg)
	return &reply, nil
}

func notifyResponseMsg(code int64, msg string) string {
	//异步通知应答参数组装
	resData := map[string]interface{}{
		constkey.RETURN_CODE: code,
		constkey.RETURN_MSG:  msg,
		constkey.MSG_ID:      lib.GetMsgId(),
	}
	signType := lib.IcbcPay.GetSignType()
	bytes, _ := json.Marshal(resData)
	signData := "\"response_biz_content\":" + string(bytes) + "," + "\"sign_type\":" + "\"" + signType + "\""
	sign, err := lib.IcbcPay.Sign(signData)
	if err != nil {
		return ""
	}
	jsonStr := "{" + signData + ",\"sign\":\"" + sign + "\"}"
	return jsonStr
}

// 获取支付成功后金额处理
func (i *icbc) PayFund(notify *pay2.PayNotify, bill *order.ReplyGetOrderSplitBill) []bus.FundRecordItem {

	return []bus.FundRecordItem{}
}

// 获取清分金额
func (i *icbc) GetFundAmount(notify *pay2.PayNotify, bill *order.ReplyGetOrderSplitBill) string {

	return ""
}

// 获取支付方式
func (i *icbc) GetType() int {
	return order.PAY_CHANNEL_icbc
}

// 支付清分数据前置处理
func (i *icbc) AgentChannel(busClearingModel *models.BusClearingModel, list map[string]interface{}) (id int, err error) {

	return 0, nil
}

// 工行支付清分
func (i *icbc) FundAgent(ctx context.Context) (rest bool) {

	return false
}

// 工行支付清分结果异步查询
func (i *icbc) FundAgentResult(ctx context.Context) (rest bool) {

	return
}

func (i *icbc) GetInsureFund() bool {
	return false
}

func (i *icbc) AgentChannelInsure(insureClearingModel *models.InsureClearingModel, list map[string]interface{}) (id int, err error) {
	return
}

func (i *icbc) AgentChannelPlat(platClearingModel *models.PlatformClearingModel, list map[string]interface{}) (id int, err error) {
	return
}

func (i *icbc) AgentChannelRenewInsure(renewInsureClearingModel *models.RenewInsureClearingModel, list map[string]interface{}) (id int, err error) {
	return
}
